package com.eastmoney.emis.edda.task.edda;

import com.eastmoney.emis.edda.domain.entity.EddaApply;
import com.eastmoney.emis.edda.domain.repository.HsbcEddaRepository;
import com.eastmoney.emis.edda.domain.service.EddaServeTimeService;
import com.eastmoney.emis.edda.domain.valueobject.EddaApplyStatus;
import com.eastmoney.emis.edda.domain.valueobject.ServiceType;
import com.eastmoney.emis.edda.task.TaskManagement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @description: Description
 * @projectName: EDDA-HSBC
 * @package: com.eastmoney.emis.edda.task
 * @author: 汪程程
 * @date: 2022/10/10 1:44 PM
 * @version: 1.0
 */
@Component
@Async("eddaTaskExecutor")
public class EddaTaskProducer {

    private static Logger log = LoggerFactory.getLogger(EddaTaskProducer.class);

    @Autowired
    private TaskManagement taskManagement;
    @Autowired
    private HsbcEddaRepository hsbcEddaRepository;
    @Autowired
    private EddaServeTimeService eddaServeTimeService;

    @Scheduled(cron = "${emis.edda.task.edda-cron:*/30 * * * * ?}")
    public void loadEddaApplyFromDB() {
        if (!eddaServeTimeService.serving(ServiceType.EDDA)) {
            return;
        }
        List<EddaApply> eddaApplyList = hsbcEddaRepository.findAllUncompleted();
        if (eddaApplyList.isEmpty()) {
            return;
        }
        // 更新状态
        List<EddaApply> updateApplyList = eddaApplyList.stream()
                .filter(r -> EddaApplyStatus.PROCESSING.value().equals(r.getStatus()))
                .filter(filterChain())
                .collect(Collectors.toList());
        for (EddaApply eddaApply : updateApplyList) {
            taskManagement.addTask(new EddaAuthEnquiryTask(eddaApply));
        }
        // 未处理
        List<EddaApply> notCommitToBankApplyList = eddaApplyList.stream()
                .filter(r -> EddaApplyStatus.INIT.value().equals(r.getStatus()))
                .collect(Collectors.toList());
        for (EddaApply eddaApply : notCommitToBankApplyList) {
            taskManagement.addTask(new EddaAuthEnquiryTask(eddaApply));
        }
    }

    /**
     * 每天9点、12点、15点、18点查询一次
     */
    private static final int[] FIX_ENQUIRY_TIME = new int[]{
            0, 0, 0, 0,
            0, 0, 0, 0,
            0, 1, 0, 0,
            1, 0, 0, 1,
            0, 0, 1, 0,
            0, 0, 0, 0,
    };

    private Predicate<EddaApply> filterChain() {
        LocalDateTime now = LocalDateTime.now();
        Predicate<EddaApply> predicate = r -> {
            // 3 min 之内的
            LocalDateTime start = now.minusMinutes(3).withSecond(0);
            return r.getCreatedTime().isAfter(start);
        };
        return predicate.or(r -> {
            // 15 min
            LocalDateTime start = now.minusMinutes(15).withSecond(0);
            LocalDateTime end = now.minusMinutes(15).withSecond(59);
            LocalDateTime createdTime = r.getCreatedTime();
            return createdTime.isAfter(start) && createdTime.isBefore(end);
        }).or(r -> {
            // 1h
            LocalDateTime start = now.minusHours(1).withSecond(0);
            LocalDateTime end = now.minusHours(1).withSecond(59);
            LocalDateTime createdTime = r.getCreatedTime();
            return createdTime.isAfter(start) && createdTime.isBefore(end);
        }).or(r -> FIX_ENQUIRY_TIME[now.getHour()] > 0
                && r.getCreatedTime().until(now, ChronoUnit.HOURS) >= 1
                && !now.truncatedTo(ChronoUnit.HOURS).isEqual(r.getUpdatedTime().truncatedTo(ChronoUnit.HOURS))
        );
    }


}
